/*
 * -------------------------------------------------------------------------
 * dwt1d.c -- 1-D signal decomposition and reconstruction
 * SWT - Scilab wavelet toolbox
 * Copyright (C) 2005-2006  Roger Liu
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * -------------------------------------------------------------------------
 */
#include "dwt.h"
#include "parameters.h"
#include "arq.h"

#if ARQ_x86 == 0
#include <dsplib.h>
#endif

extend_method dwtMode = SYMH;

/*-------------------------------------------
 * wavelet name parser
 *-----------------------------------------*/

#if 0

void
dwt_write(char *mode, int *errCode) {
    *errCode = UNKNOWN_INPUT_ERR;

#if METHOD == ASYMH || METHOD == SYMH
    dwtMode = METHOD;
    *errCode = SUCCESS;
#endif

    return;
}
#endif

double sigInTemp[DWT_SIGINTEMP_LEN];
double approxTemp1[DWT_APPROXTEMP_LEN];
double approxPre1[DWT_APPROXPRE_LEN];
double detailTemp1 [DWT_APPROXPRE_LEN];
double detailPre1 [DWT_APPROXPRE_LEN];

void
dwt_neo(double *sigIn, int sigInLength, double *lowDe,
        double *hiDe, int filterLen, double *approx,
        double *detail, int sigOutLength, extend_method extMethod) {
    wextend_1D_center(sigIn, sigInLength, sigInTemp, DWT_SIGINTEMP_LEN, extMethod); /*OK*/
    conv1(sigInTemp, DWT_SIGINTEMP_LEN, approxTemp1, DWT_APPROXTEMP_LEN, lowDe, filterLen); /*OK*/
    wkeep_1D_center(approxTemp1, DWT_APPROXTEMP_LEN, approxPre1, DWT_APPROXPRE_LEN);
    dyaddown_1D_keep_even(approxPre1, DWT_APPROXPRE_LEN, approx, sigOutLength);
    conv1(sigInTemp, DWT_SIGINTEMP_LEN, detailTemp1, DWT_APPROXTEMP_LEN, hiDe, filterLen);
    wkeep_1D_center(detailTemp1, DWT_APPROXTEMP_LEN, detailPre1, DWT_APPROXPRE_LEN);
    dyaddown_1D_keep_even(detailPre1, DWT_APPROXPRE_LEN, detail, sigOutLength);
    return;
}

double approxTemp[IDWT_SIGIN_LEN];
double detailTemp[IDWT_SIGIN_LEN];
double approxPre[IDWT_SIGOUT_LEN];
double detailPre[IDWT_SIGOUT_LEN];
double sigOutPre[IDWT_SIGOUT_LEN];

void
idwt_neo(double *approx, double *detail, int sigInLength,
        double *lowRe, double *hiRe, int filterLen,
        double *sigOut, int sigOutLength) {
    int count;
    dyadup_1D_feed_even(approx, sigInLength, approxTemp, IDWT_SIGIN_LEN);
    dyadup_1D_feed_even(detail, sigInLength, detailTemp, IDWT_SIGIN_LEN);
    conv2(approxTemp, IDWT_SIGIN_LEN, approxPre, IDWT_SIGOUT_LEN, lowRe, filterLen);
    conv2(detailTemp, IDWT_SIGIN_LEN, detailPre, IDWT_SIGOUT_LEN, hiRe, filterLen);
    for (count = 0; count < IDWT_SIGOUT_LEN; count++)
        sigOutPre[count] = approxPre[count] + detailPre[count];
    wkeep_1D_center(sigOutPre, IDWT_SIGOUT_LEN, sigOut, sigOutLength);
    return;
}
